"""
Copyright (c) 2023 - present SKbioinfo
"""

from flask_restful import Resource, request,reqparse
from flask import jsonify
from flask_login import login_required
from flask_login import current_user

from apps.NGS_API.common.common_time import *
from apps.NGS_API.common.db_table_config import *
from apps.NGS_API.record.history_util import *
from apps.NGS_API.record.interface_operate_his import parse_reason

from apps.NGS_API.utils.log_helper import lg
from apps.NGS_API.sample.db_sample import *
from apps.NGS_API.connector.db_common import *
from apps.NGS_API.sample.utils import *
pm = operation_monitor(table_name=ngs_op_log["name"])

class interfaceOutamountID(Resource):
    @login_required
    def put(self,id):
        try:
            parser = reqparse.RequestParser()
            parser.add_argument("sam_id",type=str, help="样品编号输入有误！",required=True)
            parser.add_argument("cur_amount",type=str,help="现有样品量输入错误！",required=True)
            parser.add_argument("out_amount",type=str,help="出库样品量输入错误！",required=True)
            args=parser.parse_args()
            cur_amount = float(args.get("cur_amount")) - float(args.get("out_amount"))
            ### record user operation ###
            record_user_operate(
                pm = pm,
                current_user = current_user,
                record_table = ngs_op_log["name"],
                resource_table = sample_amount["name"],
                ch_user = current_user,
                type_name = "put",
                cols = sample_amount["match"],       
                id = id,
                later_infos = args
            )
  
            ### SQL: update sample current amount ### 
            cols = '''
                cur_amount = {cur_amount}
            '''.format(
                cur_amount=cur_amount
            )
            update_sql = '''
                UPDATE {table_name} SET  
                    {cols}
                WHERE {col_name} = {col}            
            '''.format(
                cols = cols,
                table_name = sample_stock_db["name"],
                col_name= "sample_id",
                col = id
            )
            update_info(update_sql)
        except Exception as e:
            lg.error(e)

class interfaceOutstockID(Resource):
    
    def __init__(self):
        self.sam_log = sample_stock_log(form=sample_log) 
    
    @login_required
    def delete(self,id):
        try:
            if request.data.decode(encoding='UTF-8',errors='strict') == "-1":
                pass
            else:
                ### SQL: record user operation ###
                record_user_operate(
                    pm = pm,
                    current_user = current_user,
                    record_table = ngs_op_log["name"],
                    resource_table = sample_db["name"],
                    ch_user = current_user,
                    type_name = "outstock",
                    cols = '''
                        sample_id
                    ''',
                    id = id,
                    reason_details = "样品清退"
                )
                ### SQL: query outstock sample id ###
                query_sql = '''
                    SELECT 
                        {col} 
                    FROM 
                        {table_name}
                '''.format(
                    col = sample_db["match"]["sam_id"].split("|")[0],
                    table_name = sample_db["name"]
                )
                tmp_result = query_info(query_sql)
                if len(tmp_result) == 0 or tmp_result == None:
                    pass
                else:
                    delete_id = tmp_result[0][0]
                    ### SQL: delete stock infos ###
                    stock_delete_sql = "DELETE FROM {table_name} WHERE {db_name} = \"{col_value}\"".format(
                        table_name = sample_stock_db["name"],
                        db_name = sample_db["match"]["sam_id"].split("|")[0],
                        col_value = delete_id
                    )
                    ### STEP 1: delete stock infos ###
                    delete_info(delete_sql=stock_delete_sql)
                    ### SQL：sample outstock ###
                    delete_sql = "DELETE FROM {table_name} WHERE {db_name} = \"{col_value}\"".format(
                        table_name = sample_db["name"],
                        col_value = id,
                        db_name = "id"
                    )
                    ### SQL：sample outstock log ###
                    self.sam_log.sample_outstock_log(
                        infos ={
                            "sample_id": delete_id
                        }
                    )
                    ### STEP 2: outstock samples ###
                    delete_info(delete_sql=delete_sql)
                return id
        except Exception as e:
            lg.error(e)
            
    @login_required   
    def post(self,id):
        try:
            ### SQL: record user operation ###
            record_user_operate(
                pm = pm,
                current_user = current_user,
                record_table = ngs_op_log["name"],
                resource_table = sample_db["name"],
                ch_user = current_user,
                type_name = "outstock",
                cols = '''
                    sample_id
                ''',
                id = id,
                reason_details = "样品清退"
            )
            ### SQL: query outstock sample id ###
            query_sql = '''
                SELECT 
                    {col} 
                FROM 
                    {table_name}
            '''.format(
                col = sample_db["match"]["sam_id"].split("|")[0],
                table_name = sample_db["name"]
            )
            ### stock results ###
            tmp_result = query_info(query_sql)
            if len(tmp_result) == 0 or tmp_result == None:
                pass
            else:
                delete_id = tmp_result[0][0]
                ### SQL: delete stock infos ###
                stock_delete_sql = "DELETE FROM {table_name} WHERE {db_name} = \"{col_value}\"".format(
                    table_name = sample_stock_db["name"],
                    db_name = sample_db["match"]["sam_id"].split("|")[0],
                    col_value = delete_id
                )
                ### STEP 1: delete stock infos ###
                delete_info(delete_sql=stock_delete_sql)
                ### SQL: sample outstock ###
                outstock_sample_sql = "DELETE FROM {table_name} WHERE {db_name} =\"{col_value}\"".format(
                        table_name = sample_db["name"],
                        col_value=id,
                        db_name="id"
                )
                self.sam_log.sample_outstock_log(
                    infos ={
                        "sample_id": delete_id
                    }
                )
                ### STEP 2: outstock sample infos ###
                delete_info(outstock_sample_sql)
        except Exception as e:
            lg.error(e)

'''
    URL: /NGS/EXP_NGS_upload
'''
class interfaceSampleStock(Resource):
    @login_required
    def get(self):
        sample_stock_sql = '''
            SELECT
                sam.id,
                sam.sample_id,
                sam.primary_project_id,
                sam.primary_sample_id,
                sam.unit,
                sam.init_concen,
                sam.init_volume,
                proj.project_id,
                sam.operate_user,
                sam.check_user,
                sam.sample_source,
                sam.sample_type,
                sam.sample_name,
                sam.init_amount,
                sam.cur_amount,
                sam.create_time,
                sam.modify_time,
                sam_stc.cur_amount,
                sam_stc.status
            FROM {table_one} as proj
            LEFT JOIN {table_two} as sam
            ON proj.project_id = sam.project_id
            LEFT JOIN {table_three} as sam_stc
            ON sam.sample_id = sam_stc.sample_id
        '''.format(
            table_one = project_db["name"],
            table_two = sample_db["name"],
            table_three = sample_stock_db["name"]
        )
        sample_stock_infos = dic_query_info(sample_stock_sql)
        ### SQL: collect sample Infos ###
        status_mapping = {
            None:"NA",
            1:"入库",
            -1:"出库",
            0:"未入库"
        }
        sample_infos = []
        for sample in sample_stock_infos:
            instock_amount = 0
            if sample["sam_stc.cur_amount"] == None:
                pass
            else:
                instock_amount = sample["sam_stc.cur_amount"]
            unit=[]
            if sample["unit"] == None:
                unit=["NA","NA"]
            else:
                unit = sample["unit"].split(",")
            sample_infos.append({
                "id":sample["id"],
                "pri_proj_id":sample["primary_project_id"],
                "pri_sam_id":sample["primary_sample_id"],
                "sam_id":sample["sample_id"],
                "proj_id":sample["project_id"],
                "op_user":sample["operate_user"],
                "ch_user":sample["check_user"],
                "sam_source":sample["sample_source"],
                "sam_type":sample["sample_type"],
                "sam_name":sample["sample_name"],
                "init_concen":str(sample["init_concen"]) + " (" + unit[0] + ")",
                "init_volume":str(sample["init_volume"]) + "/" + unit[1],
                # "init_amount":str(sample["init_amount"]) + "/" + str(unit),
                "cur_amount":str(sample["cur_amount"]) + "/" + unit[1],
                "cre_time":sample["create_time"],
                "md_time":sample["modify_time"],
                "istc_amount":str(instock_amount) + "/" + unit[1],
                "status":status_mapping[sample["status"]],
                "istc_user":current_user.username,
                "istc_ch_user":current_user.username,
                "flag":False
            })
        response = jsonify(sample_infos)
        response.status = 202
        return response
    
    @login_required
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("proj_id",type=str,required=True,help="项目编号输入错误！")
        parser.add_argument("sam_id",type=str,required=True,help="项目编号输入错误！")
        parser.add_argument("init_amount",type=str,required=True,help="样品量输入有误！")
        parser.add_argument("cur_amount",type=str,required=True,help="现有样品量输入有误！")
        parser.add_argument("istc_amount",type=str,required=True,help="库存样品量输入有误！")
        parser.add_argument("istc_user",type=str,required=True,help="入库用户输入错误！")
        parser.add_argument("istc_ch_user",type=str,required=True,help="入库审核人输入错误！")
        args = parser.parse_args()
        ### SQL: instock sample amount ###
        cols = '''
            instock_user = \"{istc_user}\",
            instock_check_user = \"{istc_ch_user}\",
            instock_amount = {istc_amount},
            cur_amount = {cur_amount},
            status = 1
        '''.format(
            istc_user = args.get("istc_user"),
            istc_ch_user = args.get("istc_ch_user"),
            istc_amount = float(args.get("istc_amount").split("/")[0]),
            cur_amount = float(args.get("istc_amount").split("/")[0]),
        )
        instock_sample_sql = '''
            UPDATE {table_name} SET 
                {cols}
            WHERE {col_name} = \"{col_val}\"
        '''.format(
            table_name = sample_stock_db["name"],
            cols = cols,
            col_name = sample_stock_db["match"]["sam_id"].split("|")[0],
            col_val = args.get("sam_id")
        )
        update_info(instock_sample_sql)

class interfaceSamtableStock(Resource):
    @login_required
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("id",type=str,required=True,help="项目编号输入错误！")
        parser.add_argument("proj_id",type=str,required=True,help="项目编号输入有误！")
        parser.add_argument("sam_id",type=str,required=True,help="样品编号输入有误！")
        parser.add_argument("sam_source",type=str,required=True,help="样品来源输入有误！")
        parser.add_argument("sam_name",type=str,required=True,help="样品名称输入有误！")
        parser.add_argument("sam_type",type=str,required=True,help="样品类型输入有误！")
        parser.add_argument("con_unit",type=str,required=True,help="浓度单位输入有误！")
        parser.add_argument("vol_unit",type=str,required=True,help="体积单位输入有误！")
        parser.add_argument("init_volume",type=float,required=True,help="初始体积输入有误！")
        parser.add_argument("init_concen",type=float,required=True,help="初始浓度输入有误！")
        parser.add_argument("init_amount",type=float,required=True,help="初始样品量输入有误！")
        parser.add_argument("cur_amount",type=float,required=True,help="现存样品量输入有误！")
        parser.add_argument("istc_user",type=str,required=True,help="操作人输入有误！")
        parser.add_argument("istc_ch_user",type=str,required=True,help="审核人输入有误！")
        # parser.add_argument("status",type=str,required=True,help="样品状态输入有误！")
        args = parser.parse_args()
        cols ='''
            primary_project_id,
            primary_sample_id,
            project_id,
            sample_id,
            sample_source,
            sample_name,
            sample_type,
            init_concen,
            init_volume,
            init_amount,
            cur_amount,
            unit,
            operate_user,
            check_user,
            create_time,
            modify_time
        '''
        values = '''
            \"{primary_project_id}\",
            \"{primary_sample_id}\",
            \"{project_id}\",
            \"{sample_id}\",
            \"{sample_source}\",
            \"{sample_name}\",
            \"{sample_type}\",
            {init_concen},
            {init_volume},
            {init_amount},
            {cur_amount},
            \"{unit}\",
            \"{operate_user}\",
            \"{check_user}\",
            \"{cre_time}\",
            \"{md_time}\"
        '''.format(
            primary_project_id = args.get('proj_id'),
            primary_sample_id = args.get('sam_id'),
            project_id = args.get('proj_id'),
            sample_id = args.get('sam_id'),
            sample_source = args.get('sam_source'),
            sample_name = args.get('sam_name'),
            sample_type = args.get('sam_type'),
            init_concen = args.get('init_concen'),
            init_volume = args.get('init_volume'),
            init_amount = args.get('init_amount'),
            cur_amount = args.get('init_volume'),
            unit = args.get("con_unit") + "," + args.get("vol_unit"),
            operate_user = args.get('istc_user'),
            check_user = args.get('istc_ch_user'),
            cre_time = get_current_time(),
            md_time = get_current_time()
        )
        '''
            SQL: sample instock sql 
        '''
        sample_record_sql = '''
            INSERT INTO {table_name} ( 
                    {cols} 
            ) VALUES (
                    {values}
            )
        '''.format(
            table_name = sample_db["name"],
            cols = cols,
            values = values
        )
        '''
            instock cols
        '''
        instock_cols ='''
            primary_sample_id,primary_project_id,
            sample_id,project_id,stock_label,
            stock_locale,instock_type,
            instock_user,instock_check_user,
            instock_amount,instock_time,
            cur_amount,outstock_type,
            outstock_user,outstock_check_user,
            outstock_amount,outstock_time,
            create_time,modify_time,
            stock_id,status
        '''
        col_values ='''
            \"{primary_sample_id}\",\"{primary_project_id}\",
            \"{sample_id}\",\"{project_id}\",\"{stock_label}\",
            \"{stock_locale}\",{instock_type},
            \"{instock_user}\",\"{instock_check_user}\",
            {instock_amount},\"{instock_time}\",
            {cur_amount},{outstock_type},
            \"{outstock_user}\",\"{outstock_check_user}\",
            {outstock_amount},\"{outstock_time}\",
            \"{create_time}\",\"{modify_time}\",
            \"{stock_id}\",{status}
        '''.format(
            primary_project_id = args.get('proj_id'),
            primary_sample_id = args.get('sam_id'),
            sample_id=args.get("sam_id"), 
            project_id=args.get("project_id"),
            stock_label=args.get("stock_label"),
            stock_locale=args.get("stock_locale"), 
            instock_type=0, instock_user="", instock_check_user="",
            instock_amount=0, instock_time=get_current_time(),
            cur_amount=0, outstock_type=-1,
            outstock_user="", outstock_check_user="",
            outstock_amount=0, outstock_time=get_current_time(),
            create_time=get_current_time(), modify_time=get_current_time(),
            stock_id="",status=0
        )
        sample_instock_sql='''
            INSERT INTO {table_name} (
                {cols}
            ) VALUES (
                {col_values}
            )
        '''.format(
            table_name=sample_stock_db["name"],
            cols=instock_cols,
            col_values=col_values
        )
        ### STEP 1: record sample infos ###
        add_info(sample_record_sql)
        ### STEP 2: instock sample infos ###
        add_info(sample_instock_sql)